package com.sicheng.metadata.juc.future;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author zsc
 * @version 1.0
 * @date 2022/3/31 9:36
 */
public class FutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        kill();
        System.out.println("正在后台处理请求");
        TimeUnit.MILLISECONDS.sleep(100 * 120);
    }

    private static void kill() {
        long start = System.currentTimeMillis();
        // 任务1 耗时300ms
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(300);
                return 0;
            } catch (Exception e) {
                System.out.println("发生异常");
            }
            return -1;
        });
        // 任务2 耗时200ms
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(200);
                return 0;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return -1;
        });
        System.out.println("任务提交");
        try {
            System.out.println("等待任务执行完");
            CompletableFuture.allOf(future1, future).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        // 最终耗时 300ms左右 。同步执行500ms左右
        System.out.println(end - start);
    }

    // 场景延续
    // 当多个任务相互独立时，可以进行一定的编排
    // 比如 a ,b , c 互不影响 每个任务300ms
    // d需要200ms 但是需要a的结果, 那么将a ,b , c异步执行.等待a执行完(a完成其实b,c也差不多执行完毕)拿着结果执行d,最终耗时500ms左右
    // CompletableFuture 非常重要,经常被使用
    //allOf(CompletableFuture<?>... cfs)：这个方法会返回一个全新的CompletableFuture，传递进去的所有CompletableFuture执行完才算是执行完成。
    //anyOf(CompletableFuture<?>... cfs)：这个方法会返回一个全新的CompletableFuture，只要传递进去的有一个CompletableFuture执行完，就算是执行完成
    //completedFuture(U value) ：可以假设一个执行出了一个结果，进行下面的级联操作。
    //runAsync：异步的执行Runnable，没有返回值。
    //supplyAsync：异步的执行Supplier实例，会有返回值。
}
